using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

using Advent.aiDevices;

namespace Advent.Controls
{
    /// <summary>
    /// This user control exposes the user interface which manipulates a single
    /// ToneGenerator object.
    /// </summary>
    public partial class ToneGen : UserControl
    {
        private ToneGenerator Tone = null;

        #region Contructor etc

        public ToneGen()
        {
            InitializeComponent();

            cbo_Shape.Items.Add(Waveshape.Sinusoiodal);
            cbo_Shape.Items.Add(Waveshape.Triangular);
            cbo_Shape.Items.Add(Waveshape.Square);
            this.EnabledChanged += new EventHandler(ToneGeneratorCtrl_EnabledChanged);

            cbo_Shape.SelectedIndexChanged += new EventHandler(UpdateGenerator);
            level_Carrier.SignalLevelChanged+=new EventHandler(UpdateGenerator);
            freq_Carrier.FrequencyChanged+=new EventHandler(UpdateGenerator);
        }
            
        /// <summary>
        /// This updates the tone generator settings when the contents change
        /// </summary>
        void UpdateGenerator(object sender, EventArgs e)
        {
            try
            {
                if (Tone == null) return;
                Debug.Print("Updated tone " + Tone.Name);
                Tone.Update(ParseControlsSettings());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                RefreshControls();
            }
        }

        void ToneGeneratorCtrl_EnabledChanged(object sender, EventArgs e)
        {
            // only update the control when it is enabled
            timer_Update.Enabled = this.Enabled;
        }
        #endregion


        public void SetGenerator(ToneGenerator Tone)
        {
            this.Tone = Tone;
            RefreshControls();
            UpdateStatus();
        }


        /// <summary>
        /// Refreshes the state of each control based on the tone generator
        /// </summary>
        private void RefreshControls()
        {
            try
            {
                if (Tone == null) return;
                freq_Carrier.Freq = Tone.Frequency;
                level_Carrier.Level = Tone.Level;
                cbo_Shape.SelectedItem = Tone.Shape;
                gb_Generator.Text = Tone.ToString();
            }
            catch { }
        }

        private void UpdateStatus()
        {
            try
            {
                if (Tone == null) return;
                String Msg = Tone.Name;
                if (Tone.IsActive) Msg = Msg + " (Active)";
                if (Tone.IsReserved) Msg = Msg + (" RESERVED");
                gb_Generator.Text = Msg;
            }
            catch { }
        }
        private void UpdateGenerator()
        {
            if (Tone == null) return;
            Tone.Update(ParseControlsSettings());
        }



        /// <summary>
        /// This returns a Tone object based on the current user specified settings
        /// </summary>
        private Tone ParseControlsSettings()
        {

            return new Tone(level_Carrier.Level, 
                            freq_Carrier.Freq, 
                            cbo_Shape.SelectedItem as Waveshape);
        }

        private void btn_Generate_Click(object sender, EventArgs e)
        {
            try
            {
                Tone.Generate(ParseControlsSettings(), Phase.InDegrees(0));
                RefreshControls();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btn_Stop_Click(object sender, EventArgs e)
        {
            try
            {
                Tone.StopGenerator();
                RefreshControls();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void timer_Update_Tick(object sender, EventArgs e)
        {
            try
            {
                UpdateStatus();
            }
            catch { }
        }


    }
}
